package com.neeraj.SharingArtifacts;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class RecorderActivity extends Activity implements LocationListener, OnCancelListener {
	private static final String DEBUG_TAG = "AudioRecorder";
	private static final int MEDIA_TYPE_AUDIO = 2;
	private static final String AUDIO_RECORDER_FILE_EXT_3GP = ".3gp";
	private static final String AUDIO_RECORDER_FILE_EXT_MP4 = ".mp4";
	private static final int WAIT_DIALOG_ID = 1;
	private String filename = null;
	private MediaRecorder recorder = null;
	private int currentFormat = 0;
	private int output_formats[] = { MediaRecorder.OutputFormat.MPEG_4, MediaRecorder.OutputFormat.THREE_GPP };
	private String file_exts[] = { AUDIO_RECORDER_FILE_EXT_MP4, AUDIO_RECORDER_FILE_EXT_3GP }; 
    
	private LocationManager locationManager;
	private Location location;
	private String bestProvider;	
	private File file=null;
	
	DatabaseHelper dbHelper;

    @SuppressWarnings("deprecation")
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.use_rec);
		    
		setButtonHandlers();
		enableButtons(false);
		setFormatButtonCaption();

		if (!Geocoder.isPresent()){
			Toast.makeText(getBaseContext(),
    	    "Sorry! Geocoder service not Present.",
    	    Toast.LENGTH_LONG).show();
		}
		showDialog(WAIT_DIALOG_ID);
 		locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);     		

   		Criteria criteria = new Criteria();
   		criteria.setAccuracy(Criteria.ACCURACY_COARSE);
  		criteria.setAccuracy(Criteria.ACCURACY_FINE);
   		bestProvider = locationManager.getBestProvider(criteria, false);

   		location = locationManager.getLastKnownLocation(bestProvider);
    }

	@Override
	public void onStart()
	{
		try {
			super.onStart();
			dbHelper=new DatabaseHelper(this);
			dbHelper.insertTypeData();
		} catch(Exception ex) {			
			CatchError(ex.toString());
		}
	}
	
	@Override
    protected void onResume() {
		super.onResume();		
		locationManager.requestLocationUpdates(bestProvider, 1000, 1, this);
	}

	/** Stop the updates when Activity is paused */
	@Override
	protected void onPause() {
		super.onPause();
		locationManager.removeUpdates(this);
	}

	    private void setButtonHandlers() {
	    	((Button)findViewById(R.id.btnStart)).setOnClickListener(btnClick);
	    	((Button)findViewById(R.id.btnStop)).setOnClickListener(btnClick);
	    	((Button)findViewById(R.id.btnFormat)).setOnClickListener(btnClick);
	    }
	    
	    private void enableButton(int id,boolean isEnable){
	        ((Button)findViewById(id)).setEnabled(isEnable);
	    }
	    
	    private void enableButtons(boolean isRecording) {
	        enableButton(R.id.btnStart,!isRecording);
	        enableButton(R.id.btnFormat,!isRecording);
	        enableButton(R.id.btnStop,isRecording);
	    }
	    
	    private void setFormatButtonCaption(){
	        ((Button)findViewById(R.id.btnFormat)).setText(getString(R.string.audio_format) + " (" + file_exts[currentFormat] + ")");
	    }
    
	    private String getFilename(int type){  	
	    	File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
		              Environment.DIRECTORY_DCIM), "SharingArtifacts/audio");
	
		    // Create the storage directory if it does not exist
		    if (! mediaStorageDir.exists()){
		        if (! mediaStorageDir.mkdirs()){
		            Log.d(DEBUG_TAG, "failed to create directory");
		            return null;
		        }
		    }
	
		    // Create a media file name
		    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new java.util.Date());
		    File mediaFile;
		    if(type == MEDIA_TYPE_AUDIO) {
		    	Log.d(DEBUG_TAG, "mediaStorageDir:" + mediaStorageDir.toString());
		        mediaFile = new File(mediaStorageDir.getPath() + File.separator +
		        "AUD_"+ timeStamp + file_exts[currentFormat]);
		        Log.d(DEBUG_TAG, "mediaFile:" + mediaFile.toString());
		    } else {
		        return null;
		    }
		    Log.d(DEBUG_TAG, "mediaFile Out:" + mediaFile.toString());
		    return mediaFile.getPath();
	    }
    
	    private void startRecording(){
	    	recorder = new MediaRecorder();
	            
	        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
	        recorder.setOutputFormat(output_formats[currentFormat]);
	        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
	        filename = getFilename(MEDIA_TYPE_AUDIO);
	        recorder.setOutputFile(filename);
	        
	        recorder.setOnErrorListener(errorListener);
	        recorder.setOnInfoListener(infoListener);
	            
	        try {
	            recorder.prepare();
	            recorder.start();
	            Toast.makeText(this, "Recording Started", Toast.LENGTH_LONG).show();
	        } catch (IllegalStateException e) {
	            e.printStackTrace();
	        } catch (IOException e) {
	        	e.printStackTrace();
	        }
	    }
    
	    private void stopRecording(){
	    	if(null != recorder){
	    		recorder.stop();
	            recorder.reset();
	            recorder.release();
	            
	            recorder = null;	            
	            Toast.makeText(this, "Audio file saved to: " + filename, Toast.LENGTH_LONG).show();
	            file = new File(filename);
				Log.d(DEBUG_TAG, "in on create" + location.getLatitude() + ", " + location.getLongitude());
		   		saveAttributes();
	    	}
	    }
    
    	private void displayFormatDialog(){
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            String formats[] = {"MPEG 4", "3GPP"};
            
            builder.setTitle(getString(R.string.choose_format_title))
                       .setSingleChoiceItems(formats, currentFormat, new DialogInterface.OnClickListener() {
                            
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                    currentFormat = which;
                                    setFormatButtonCaption();
                                    
                                    dialog.dismiss();
                            }
                       })
                       .show();
    	}
    
    	private MediaRecorder.OnErrorListener errorListener = new MediaRecorder.OnErrorListener() {
            @Override
            public void onError(MediaRecorder mr, int what, int extra) {
                    Log.i(DEBUG_TAG, "Error: " + what + ", " + extra);
            }
    	};
    
    	private MediaRecorder.OnInfoListener infoListener = new MediaRecorder.OnInfoListener() {
            @Override
            public void onInfo(MediaRecorder mr, int what, int extra) {
                    Log.i(DEBUG_TAG,"Warning: " + what + ", " + extra);
            }
    	};

    	private View.OnClickListener btnClick = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                    switch(v.getId()){
                            case R.id.btnStart:{
                                    Log.i(DEBUG_TAG, "Start Recording");
                                    
                                    enableButtons(true);
                                    startRecording();
                                                    
                                    break;
                            }
                            case R.id.btnStop:{                                    
                                    Log.i(DEBUG_TAG, "Stop Recording");
                                    enableButtons(false);
                                    stopRecording();
                                    
                                    break;
                            }
                            case R.id.btnFormat:{
                                    displayFormatDialog();
                                    
                                    break;
                            }
                    }
            }
    	}; 

	private String getDate() {
		String date;
		final Calendar c = Calendar.getInstance();
		int myYear = c.get(Calendar.YEAR);
		int myMonth = c.get(Calendar.MONTH);
		String monthStr=null;
//		String dayStr = null;
		if(myMonth < 10 )
			monthStr = "0"+String.valueOf(myMonth+1);
		int myDay = c.get(Calendar.DAY_OF_MONTH);
//		if(myDay < 10)
//			dayStr = "0"+String.valueOf(myDay);
		
		date = String.valueOf(myYear) + "-"
			       + monthStr + "-" + String.valueOf(myDay);
		
		return date;
	}
	
	void CatchError(String Exception) {	    	
    	Dialog diag=new Dialog(this);
    	diag.setTitle("Error!!!");
    	TextView txt=new TextView(this);
    	txt.setText(Exception);
    	diag.setContentView(txt);
    	diag.show();
    }
	
	void saveAttributes() {
		Log.d(DEBUG_TAG, "in save attributes!!!");
		Bundle b = new Bundle();
		b.putDouble("latitude", getLatitude());
		b.putDouble("longitude", getLongitude());
		b.putDouble("altitude", getAltitude());
		b.putLong("utc_time", getTime());
		b.putString("date", getDate());
		b.putString("artifactType", "audio");
		b.putString("content", file.getPath());
		b.putString("content_file_name", file.getName());
		b.putInt("isUpload", 0);
		
		dbHelper.insertData(b, MEDIA_TYPE_AUDIO);
	}
	
	protected Dialog onCreateDialog(int id) {
   	 // TODO Auto-generated method stub
   	 Dialog alertDialog = null;;
   	    switch(id) {
   	    case WAIT_DIALOG_ID:
   			alertDialog = new ProgressDialog(this);
   			((ProgressDialog)alertDialog).setMessage("Waiting for GPS location...");
   			alertDialog.setCancelable(true);
   			alertDialog.setOnCancelListener(this);
   			break;
   	    }
   	    return alertDialog;
   }
   
	@SuppressWarnings("deprecation")
	@Override
	public void onCancel(DialogInterface dialog) {
		// TODO Auto-generated method stub
		removeDialog(WAIT_DIALOG_ID);
	}

	@SuppressWarnings("deprecation")
	@Override
	public void onLocationChanged(Location loc) {
		// TODO Auto-generated method stub
		location = loc;
	    location.getLatitude();
	    location.getLongitude();
//	    dismissDialog(WAIT_DIALOG_ID);
	    removeDialog(WAIT_DIALOG_ID);
	    String Text = "My current location is:" + "Latitude = " + 
	    		location.getLatitude() + ",Longitude = " + location.getLongitude();
	    Toast.makeText( this, Text, Toast.LENGTH_SHORT).show();
	}

	@Override
	public void onProviderDisabled(String provider) {
		// TODO Auto-generated method stub
		Toast.makeText( this, "Gps Disabled", Toast.LENGTH_SHORT ).show();
	}

	@Override
	public void onProviderEnabled(String provider) {
		// TODO Auto-generated method stub
		Toast.makeText( this, "Gps Enabled", Toast.LENGTH_SHORT ).show();
	}

	@Override
	public void onStatusChanged(String provider, int status, Bundle extras) {
		// TODO Auto-generated method stub		
	}
	
	double getLatitude() {
		return location.getLatitude();
	}
	
	double getLongitude() {
		return location.getLongitude();
	}
	
	double getAltitude() {
		return location.getAltitude();
	}
	
	long getTime() {
		return location.getTime();
	}
}